package models

import (
	"encoding/json"
	"go-admin-official/guard"
	"go-admin-official/modules/database"
)

type UserBuyPluginsModel struct {
	Base `json:"-"`

	Id          int64  `json:"id"`
	UserId      int64  `json:"user_id"`
	PluginId    int64  `json:"plugin_id"`
	OrderId     int64  `json:"order_id"`
	GoodId      int64  `json:"good_id"`
	ProductType int64  `json:"product_type"`
	CreatedAt   string `json:"created_at"`
	UpdatedAt   string `json:"updated_at"`
}

func UserBuyPlugins() UserBuyPluginsModel {
	return UserBuyPluginsModel{Base: Base{Table: "user_buy_plugins"}}
}

func (t UserBuyPluginsModel) WithTx(tx *database.SqlTx) UserBuyPluginsModel {
	t.Tx = tx
	return t
}

func (t UserBuyPluginsModel) Find(id interface{}) UserBuyPluginsModel {
	item, _ := database.Table(t.Table).Find(id)

	if item == nil {
		return UserBuyPlugins()
	}

	return t.MapToModel(item)
}

var selectBuyPluginsFields = []string{
	"mini_cover",
	"user_buy_plugins.created_at",
	"user_buy_plugins.product_type",
	"plugins.updated_at",
	"plugins.author",
	"plugins.title",
	"plugins.uuid",
	"plugins.download_url",
	"plugins.translation",
}

func (t UserBuyPluginsModel) List(param guard.PluginsBuyParam) ([]map[string]interface{}, int, bool) {
	all, _ := database.Table(t.Table).
		LeftJoin("plugins", t.Table+".plugin_id", "=", "plugins.id").
		Select(selectBuyPluginsFields...).
		Where("plugins.audit_state", "=", 1).
		OrderBy("created_at", "desc").
		All()

	count := len(all)

	for index, item := range all {

		if translation, ok := item["translation"].(string); ok {
			var trans Translation
			if err := json.Unmarshal([]byte(translation), &trans); err == nil {
				item["title"] = trans.Get(param.Lang, item["title"].(string))
				item["author"] = trans.Get(param.Lang, item["author"].(string))
			}
		}

		if index == len(all)-1 {
			item["last"] = "last"
		} else {
			item["last"] = ""
		}

		if item["product_type"] == int64(0) {
			item["product"] = "基础授权"
		} else {
			item["product"] = "高级授权"
		}

		item["download_url"] = Plugin().WithDownloadURL(item["download_url"].(string)).GetDownloadURL()

		delete(item, "translation")
	}

	if param.Page*param.PageSize > count {
		all = all[(param.Page-1)*param.PageSize:]
	} else {
		all = all[(param.Page-1)*param.PageSize : param.Page*param.PageSize]
	}

	return all, count, param.Page*param.PageSize < count
}

func (t UserBuyPluginsModel) MyBuyPluginIDs(userID int64) []int64 {
	all, _ := database.Table(t.Table).
		Where("user_id", "=", userID).
		Where("state", "=", 1).
		All()
	var ids = make([]int64, len(all))
	for key, item := range all {
		ids[key] = item["plugin_id"].(int64)
	}
	return ids
}

func (t UserBuyPluginsModel) CheckBuyOrNot(pluginID, userID int64) bool {
	item, _ := database.Table(t.Table).
		Where("user_id", "=", userID).
		Where("plugin_id", "=", pluginID).
		Where("state", "=", 1).
		First()
	return item != nil
}

func (t UserBuyPluginsModel) Update(key string, value interface{}) (int64, error) {
	return database.Table(t.Table).
		Where("id", "=", t.Id).
		Update(database.H{
			key: value,
		})
}

func (t UserBuyPluginsModel) Insert(pluginID, orderId, userID, goodID, productType int64) error {
	_, err := database.SetTx(t.Tx).Table(t.Table).
		Insert(database.H{
			"user_id":      userID,
			"plugin_id":    pluginID,
			"order_id":     orderId,
			"good_id":      goodID,
			"state":        1,
			"product_type": productType,
		})
	return err
}

func (t UserBuyPluginsModel) IsEmpty() bool {
	return t.Id == int64(0)
}

func (t UserBuyPluginsModel) IsNotEmpty() bool {
	return t.Id != int64(0)
}

func (t UserBuyPluginsModel) MapToModel(m map[string]interface{}) UserBuyPluginsModel {
	t.Id, _ = m["id"].(int64)
	t.UserId, _ = m["user_id"].(int64)
	t.PluginId, _ = m["plugin_id"].(int64)
	t.OrderId, _ = m["order_id"].(int64)
	t.GoodId, _ = m["good_id"].(int64)
	t.ProductType, _ = m["product_type"].(int64)
	t.CreatedAt, _ = m["created_at"].(string)
	t.UpdatedAt, _ = m["updated_at"].(string)
	return t
}
